﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agrement;
using analy;
using System.Threading.Tasks;
using System.Net.Http;
using System.Web.Script.Serialization;
namespace SockLib.Device
{
     class JSON:IDevice 
    {
        /// <summary>
        /// 外部传进来的参数
        /// </summary>
        Dictionary<string, object> Par = new Dictionary<string, object>();
        public void SetParars(Dictionary<string, object> Params)
        {
            Par = Params;
        }
        public   JavaScriptSerializer JS = new JavaScriptSerializer();

        #region 注册处理
        /// <summary>
        /// 收到数据是否满足注册条件
        /// </summary>
        /// <param name="Buffer">Socket收到的数据</param>
        /// <param name="DM">如果成功解析，DM写入相应信息</param>
        /// <returns>True：成功解析，False：未能解析（乱数据）</returns>
       public virtual   bool DeviceReg(byte[] Buffer, ref DeviceModel DM, out List<DeviceModel.SendMsg> Sendinfo)
        {
            try
            {
                Sendinfo = new List<DeviceModel.SendMsg>();
                DeviceModel DeviceModel = new DeviceModel();
                JSON_REG RegMsg;            
                if (!RegRull(Buffer, out  RegMsg))
                {
                    return false  ;  //未能解析，返回失败
                }                 
                DeviceModel.Uid = RegMsg.gprs_code ;
                DeviceModel.DeviceGroup = DeviceModel.Uid.Substring(1, 4); //获取组号
                DeviceModel.MobileNo = RegMsg.phone_code;  //获得手机号
                DM = DeviceModel;
                DeviceModel.SendMsg DS = new DeviceModel.SendMsg();
                DS.TargetUid = DeviceModel.Uid;
                DS.DeviceOper = Converts.DeviceOper.Register;
                DS.SendBuffer = RetRegByte(DeviceModel.Uid, "1");
                if (Convert.ToInt16(DeviceModel.Uid.Substring(0, 1)) == 1)  //第1位是1中心，其他节点
                {
                    DeviceModel.IsCenter = true;
                    Sendinfo.Add(DS);
                }
                else
                    DeviceModel.IsCenter = false;
              
                return true;   //返回注册成功
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private byte[] RetRegByte(string gprsid,string success)
        {
            JSON_RetReg JReturn = new Device.JSON_RetReg();
            JReturn.gprs_code = gprsid;
            JReturn.success = success;
            string jsonstr = JS.Serialize (JReturn);
            byte[] returbyte = System.Text.Encoding.Default.GetBytes(jsonstr);
            return returbyte;
        }


        /// <summary>
        /// 这是一个第三方设备
        /// </summary>
        /// <returns></returns>
        public  virtual  string DeviceType()
        {
            return "客户端";
        }

        /// <summary>
        /// <para>服务器读取看是否有该key存在</para>
        /// <para>存在该值返回true</para>
        /// <para>不存在返回false</para>
        /// </summary>
        /// <param name="key">用户身份认证key值</param>
        /// <returns></returns>
        private bool ReadKey(string key)
        {
            //DataBaseApi.API api = new DataBaseApi.API();
            //return api.IsRegisters(key);
            return true;
        }


    

        /// <summary>
        /// <para>身份信息验证</para>
        /// </summary>
        /// <param name="Buffer">SOCKET接收到的数据</param>
        /// <param name="reg">JSON反序列得到的对象</param>
        /// <returns></returns>
        private bool RegRull(byte[] Buffer, out JSON_REG reg)
        {
            reg = new Device.JSON_REG();
            try
            {
                List<byte[]> RegList = new List<byte[]>();
                RegList=GetJson(Buffer );
                if (RegList.Count > 0)
                {
                    foreach (byte[] msg in RegList)
                    {
                        string rec = System.Text.Encoding.Default.GetString(msg);
                        JSON_REG JR = JS.Deserialize<JSON_REG>(rec);
                        reg = JR;
                        if ((JR.gprs_code == null) || (JR.phone_code == null) || (JR.user_key == null))
                            return false;
                        if (!ReadKey(JR.user_key))
                            return false;                       
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                logexception.WriteLogToFile(ex);
                string msg = ex.Message;
                return false;
            }
        }


        /// <summary>
        /// 收到byte[]中，把{}中的数据变成list<byte[]>中一项
        /// </summary>
        /// <param name="reg">注册的数组</param>
        /// <returns></returns>
        private List<byte[]> GetJson(byte[] reg)
        {
            List<byte> ReadJson = new List<byte>();
            ReadJson.AddRange(reg);
            List<byte[]> RetJson = new List<byte[]>();
            while(ReadJson.Count >0 )
            {
                int StartCharInt = 0;
                int  EndCharInt=0;
                if (ReadJson[0] == 0x7b)
                {
                    List<byte> readbyte = new List<byte>();
                    int RemoveCount = 0;
                    for (int i = 0; i < ReadJson.Count; i++)
                    {
                        if (ReadJson[i] == 0x7b)
                            StartCharInt += 1;
                        if (ReadJson[i] == 0x7d)
                            EndCharInt += 1;
                            readbyte.Add(ReadJson[i]);
                        if (StartCharInt == EndCharInt)
                        {
                            RetJson.Add(readbyte.ToArray());
                            ReadJson.RemoveRange(0, i);
                            RemoveCount = i;
                            break;
                        }
                    }
                    if (RemoveCount == 0)
                        ReadJson.RemoveAt(0);
                }
                else
                    ReadJson.RemoveAt(0); 
            }
            return RetJson;
        }


        #endregion


        #region 获取数据转发结构
        /// <summary>
        /// 数据转发规则，数据发送给节点
        /// </summary>
        /// <param name="ReceiveData"></param>
        public bool TransferRule(byte[] ReceiveData, out List<DeviceModel.SendMsg> Sendinfo)
        {
            Sendinfo = new List<DeviceModel.SendMsg>();
            List<byte[]> JSONSTR = new List<byte[]>();
            JSONSTR = GetJson(ReceiveData);
            foreach (byte[] msg in JSONSTR)
            {
                string rec = System.Text.Encoding.Default.GetString(msg);
                JSON_CMDModel JC = JS.Deserialize<JSON_CMDModel>(rec);
                List<byte> sendmsg = new List<byte>();
                Send_Agreement SA = new Send_Agreement();
                if (JC.gprs_code == null || JC.network_way == null )
                    continue;
                if (JC._list != null)
                {
                    if (JC._list.Length > PackNumber)
                    {
                        continue;
                    }
                    for (int i = 0; i < JC._list.Length; i++)
                    {
                        byte[] wirelesscode = new byte[] { (byte)(JC._list[i].wirless_code / 256), (byte)(JC._list[i].wirless_code % 256) };
                        byte[] send = SA.Make_AgreementCenter(Convert.ToByte(JC._list[i].device_type), Convert.ToByte(JC._list[i].device_cmd), JC._list[i].device_code, JC._list[i].device_data);
                        List<byte> listsend = new List<byte>();
                        listsend.AddRange(wirelesscode);
                        listsend.AddRange(send);
                        sendmsg.AddRange(listsend.ToArray());
                    }
                }

                byte[] SendByte = SA.Make_AgreementCenter(Convert.ToByte(JC.coor_type), Convert.ToByte(JC.coord_cmd), new int[] { JC.coord_code }, sendmsg.ToArray());
                DeviceModel.SendMsg DS = new Device.DeviceModel.SendMsg();
                DS.TargetUid = JC.gprs_code;
                DS.SendBuffer = SendByte;
                DS.DeviceOper = Converts.DeviceOper.Transfer;
                Sendinfo.Add(DS);
            }
            if (Sendinfo.Count > 0)
                return true;
            else
                return false;
        }

        private int PackNumber = 10;
        DataBaseApi.API api = new DataBaseApi.API();
        /// <summary>
        /// 节点数据转发规则，数据发送给中心
        /// </summary>
        /// <param name="ReceiveData">收到的数据</param>
        /// <param name="uid">GPRS的编号</param>
        /// <param name="Sendinfo">需要转发的结构体</param>
        /// <returns></returns>
        public   bool NodeTransferRule(byte[] ReceiveData, string uid, ref DeviceModel.SendMsg[] Sendinfos)
        {
            try
            {
                List<byte[]> returnval = new List<byte[]>();
                Send_Agreement SA = new Send_Agreement();
                returnval = SA.Read_Agreement(ReceiveData);
                List<DeviceModel.SendMsg> LDS = new List<DeviceModel.SendMsg>();
                foreach (byte[] res in returnval)
                {
                    Device.DeviceModel.SendMsg Sendinfo = new Device.DeviceModel.SendMsg();
                    Sendinfo.TargetUid = uid;
                    AnalyAgreeMent AAM = new AnalyAgreeMent();
                    string ARD = AAM.ReadAgreeMent(res);
                    RetCmd RC = new RetCmd();
                    RC = JS.Deserialize<RetCmd>(ARD);
                    RC.gprs_code = uid;
                    Sendinfo.SendBuffer = System.Text.Encoding.Default.GetBytes(JS.Serialize(RC));
                    LDS.Add(Sendinfo);
                    DataBaseApi.ControlHistory CH = new DataBaseApi.ControlHistory()
                    {
                        GPRSNumber = uid,
                        Number = RC.device_code,
                        Operate = RC.device_cmd,
                        OperateTime = DateTime.Now,
                        ReadOrWrite = false,
                        Describe = RC.explain
                    };
                    Task<bool> xx = api.SaveHistory(CH);
                }
                Sendinfos = LDS.ToArray();
                return true;
            }
            catch (Exception ex)
            {
                logexception.WriteLogToFile(ex);
                DeviceModel.SendMsg[] Sendinfo = new DeviceModel.SendMsg[1];
                Sendinfos = Sendinfo;
                return false;
            }
        }

        #endregion


        #region 数据转换

        /// <summary>
        /// 心跳包格式
        /// </summary>
        /// <param name="TargetUid">发给的中心模块ID</param>
        /// <param name="uid">在线中心模块ID集合</param>
        /// <returns></returns>
       public  List< byte[]> HeartBeatConvert(string TargetUid, string[] uid)
        {
            JSON_HEARTBEAT JH = new JSON_HEARTBEAT();
            JH.targetuid = TargetUid;
            JH.uid = uid;
            string s = JS.Serialize(JH);
            List<byte[]> LB = new List<byte[]>();
            LB.Add(System.Text.Encoding.Default.GetBytes(s));
            return LB;
            //return System.Text.Encoding.Default.GetBytes(s);
        }


        /// <summary>
        /// 发送数据转换
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] SendDataConvert(byte[] Data)
        {
            return Data;
        }

        /// <summary>
        /// 接收数据转换
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] ReceiveDataConvert(byte[] Data)
        {
            SXDataConvert.SXDataConvent SXConvert = new SXDataConvert.SXDataConvent();
            return SXConvert.Rec2Byte(Data);
            //return Data;
        }

        public byte[] DataPacket(DeviceModel.SendMsg SendMsg)
        {
            return SendMsg.SendBuffer;
        }
        #endregion



        #region 心跳包处理
        /// <summary>
        /// 心跳包不做任何转发处理
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public bool IsHeartPack(byte[] Pack)
        {
            if (Pack.Length == 1 && (Pack[0] == 0x2B || Pack[0] == 0xfe))
                return true;
            return false;

        }
        #endregion


        #region 显示LOG区发送数据
       public  string SendString(string uid, byte[] msg)
        {
            if(uid.Substring(0,1)=="1")
            return  System.Text.Encoding.Default.GetString(msg);
            else
                return Converts.byteToHexStr(msg);
        }
        #endregion 
    }
}
